package com.visionvera.retrofitservice.net;

import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;

import com.google.gson.JsonParseException;
import com.orhanobut.logger.Logger;
import com.visionvera.retrofitservice.R;
import com.visionvera.retrofitservice.dialog.CommonDialogUtils;
import com.visionvera.retrofitservice.utils.ToastUtils;

import org.json.JSONException;

import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.HttpException;

import static com.visionvera.retrofitservice.net.BaseObserver.ExceptionReason.CONNECT_ERROR;
import static com.visionvera.retrofitservice.net.BaseObserver.ExceptionReason.CONNECT_TIMEOUT;
import static com.visionvera.retrofitservice.net.BaseObserver.ExceptionReason.PARSE_ERROR;
import static com.visionvera.retrofitservice.net.BaseObserver.ExceptionReason.UNKNOWN_ERROR;

/**
 * Created by dongyukun on 2017/11/7.
 */
public abstract class BaseObserver<T> implements Observer<BaseEntity<T>> {
    //  Activity 是否在执行onStop()时取消订阅
    private boolean isAddInStop = false;
    private CommonDialogUtils dialogUtils;

    public BaseObserver(Context context) {
        if (dialogUtils == null)
            dialogUtils=new CommonDialogUtils();
        dialogUtils.showProgress(context, "Loading...");
    }

    public BaseObserver(Context context, String msg) {
        if (dialogUtils == null)
            dialogUtils=new CommonDialogUtils();
        if (TextUtils.isEmpty(msg)) {
            dialogUtils.showProgress(context);
        } else {
            dialogUtils.showProgress(context, msg);
        }
    }

    public BaseObserver(Context context, boolean isShowLoading) {
        if (dialogUtils == null)
            dialogUtils=new CommonDialogUtils();
        if (isShowLoading) {
            dialogUtils.showProgress(context,"Loading...");
        }
    }

    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(BaseEntity<T> tBaseEntity) {
        if (tBaseEntity.isSuccess()) {
            try {
                onSuccess(tBaseEntity.getData());
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            try {
                onFail(tBaseEntity);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void dismissProgress(){
        if(dialogUtils!=null){
            dialogUtils.dismissProgress();
        }
    }

    @Override
    public void onError(Throwable e) {
        Logger.e("Retrofit", e.getMessage());
        dismissProgress();
        if (e instanceof HttpException) {     //   HTTP错误
            onException(ExceptionReason.BAD_NETWORK);
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException) {   //   连接错误
            onException(CONNECT_ERROR);
        } else if (e instanceof InterruptedIOException) {   //  连接超时
            onException(CONNECT_TIMEOUT);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {   //  解析错误
            onException(PARSE_ERROR);
        } else {
            onException(UNKNOWN_ERROR);
        }
        onFinish();
    }

    @Override
    public void onComplete() {
        onFinish();
    }

    /**
     * 请求成功
     *
     * @param response 服务器返回的数据
     */
    abstract public void onSuccess(T response);

//    /**
//     * 请求数据错误
//     *
//     * @param msg 服务器返回的错误信息
//     */
//    public abstract void onError(String msg);

    /**
     * 请求结束
     */
    public abstract void onFinish();

    /**
     * 服务器返回数据，但响应码不为200
     *
     * @param response 服务器返回的数据
     */
    public void onFail(BaseEntity<T> response) {
        String message = response.getMsg();
        if (TextUtils.isEmpty(message)) {
            ToastUtils.show(R.string.response_return_error);
        } else {
            ToastUtils.show(message);
        }
    }

    /**
     * 请求异常
     *
     * @param reason
     */
    public void onException(ExceptionReason reason) {
        switch (reason) {
            case CONNECT_ERROR:
                ToastUtils.show(R.string.connect_error, Toast.LENGTH_SHORT);
                break;

            case CONNECT_TIMEOUT:
                ToastUtils.show(R.string.connect_timeout, Toast.LENGTH_SHORT);
                break;

            case BAD_NETWORK:
                ToastUtils.show(R.string.bad_network, Toast.LENGTH_SHORT);
                break;

            case PARSE_ERROR:
                ToastUtils.show(R.string.parse_error, Toast.LENGTH_SHORT);
                break;

            case UNKNOWN_ERROR:
            default:
                ToastUtils.show(R.string.unknown_error, Toast.LENGTH_SHORT);
                break;
        }
    }

    /**
     * 请求网络失败原因
     */
    public enum ExceptionReason {
        /**
         * 解析数据失败
         */
        PARSE_ERROR,
        /**
         * 网络问题
         */
        BAD_NETWORK,
        /**
         * 连接错误
         */
        CONNECT_ERROR,
        /**
         * 连接超时
         */
        CONNECT_TIMEOUT,
        /**
         * 未知错误
         */
        UNKNOWN_ERROR,
    }
}
